package com.booksystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.booksystem.common.RestResult;
import com.booksystem.dto.CreateOrderDTO;
import com.booksystem.dto.QueryOrderDetailDTO;
import com.booksystem.dto.UpdateOrderStatusDTO;
import com.booksystem.entity.*;
import com.booksystem.entity.OrderInfoDO;
import com.booksystem.entity.OrderItemDO;
import com.booksystem.exception.BusinessException;
import com.booksystem.mapper.*;
import com.booksystem.mapper.OrderInfoMapper;
import com.booksystem.mapper.OrderItemMapper;
import com.booksystem.service.OrderService;
import com.booksystem.utils.OrderNoGeneratorUtil;
import java.math.BigDecimal;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 *   订单服务实现类
 * </p>
 * @author 段伟豪
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Autowired
    private ProductInfoMapper productInfoMapper;

    @Autowired
    private InventoryLogMapper inventoryLogMapper;

    @Autowired
    private UserMapper userInfoMapper; // 修改为正确的Mapper接口

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResult<Boolean> createOrder(CreateOrderDTO createOrderDTO) {
        try {
            // 1. 校验用户是否存在
            QueryWrapper<UserDO> userQueryWrapper = new QueryWrapper<>(); // 修改为正确的实体类
            userQueryWrapper.eq("user_id", createOrderDTO.getUserId());
            UserDO userInfo = userInfoMapper.selectOne(userQueryWrapper); // 修改为正确的实体类
            if (userInfo == null) {
                return new RestResult<>("000001", "用户不存在");
            }

            // 2. 校验购物车中商品是否有效且库存充足
            List<CreateOrderDTO.Item> items = createOrderDTO.getItems();
            if (items == null || items.isEmpty()) {
                throw new BusinessException("000001", "请选择要购买的商品");
            }

            BigDecimal totalAmount = BigDecimal.ZERO;
            for (CreateOrderDTO.Item item : items) {
                QueryWrapper<ProductInfoDO> productQueryWrapper = new QueryWrapper<>();
                productQueryWrapper.eq("product_id", item.getProductId());
                ProductInfoDO productInfo = productInfoMapper.selectOne(productQueryWrapper);
                if (productInfo == null || !productInfo.getIsOnSale().equals(1)) {
                    throw new BusinessException("000001", "商品库存不足或无效");
                }
                if (item.getQuantity() > productInfo.getStockQuantity()) {
                    throw new BusinessException("000001", "商品库存不足或无效");
                }
                // 计算小计金额
                BigDecimal subtotal = productInfo.getPrice().multiply(BigDecimal.valueOf(item.getQuantity()));
                totalAmount = totalAmount.add(subtotal);
            }

            // 3. 生成唯一订单编号
            String orderNo = OrderNoGeneratorUtil.generateOrderNo();

            // 4. 保存订单主信息到order_info表
            OrderInfoDO orderInfo = new OrderInfoDO();
            orderInfo.setUserId(createOrderDTO.getUserId());
            orderInfo.setOrderNo(orderNo);
            orderInfo.setTotalAmount(totalAmount);
            orderInfo.setShippingAddress(createOrderDTO.getShippingAddress());
            orderInfo.setPaymentMethod(createOrderDTO.getPaymentMethod());
            orderInfo.setRemark(createOrderDTO.getRemark());
            orderInfo.setOrderStatus(1); // 待付款
            int insertOrderResult = orderInfoMapper.insert(orderInfo);
            if (insertOrderResult <= 0) {
                throw new BusinessException("999999", "系统异常");
            }

            // 5. 保存订单明细到order_item表
            for (CreateOrderDTO.Item item : items) {
                QueryWrapper<ProductInfoDO> productQueryWrapper = new QueryWrapper<>();
                productQueryWrapper.eq("product_id", item.getProductId());
                ProductInfoDO productInfo = productInfoMapper.selectOne(productQueryWrapper);
                OrderItemDO orderItem = new OrderItemDO();
                orderItem.setOrderId(orderInfo.getOrderId());
                orderItem.setProductId(item.getProductId());
                orderItem.setProductName(productInfo.getProductName());
                orderItem.setQuantity(item.getQuantity());
                orderItem.setUnitPrice(productInfo.getPrice());
                orderItem.setSubtotal(productInfo.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())));
                int insertItemResult = orderItemMapper.insert(orderItem);
                if (insertItemResult <= 0) {
                    throw new BusinessException("999999", "系统异常");
                }
            }

            // 6. 扣除对应商品的库存，并记录日志
            for (CreateOrderDTO.Item item : items) {
                QueryWrapper<ProductInfoDO> productQueryWrapper = new QueryWrapper<>();
                productQueryWrapper.eq("product_id", item.getProductId());
                ProductInfoDO productInfo = productInfoMapper.selectOne(productQueryWrapper);
                // 扣减库存
                productInfo.setStockQuantity(productInfo.getStockQuantity() - item.getQuantity());
                int updateProductResult = productInfoMapper.updateById(productInfo);
                if (updateProductResult <= 0) {
                    throw new BusinessException("999999", "系统异常");
                }
                // 记录库存变动日志
                InventoryLogDO inventoryLog = new InventoryLogDO();
                inventoryLog.setProductId(item.getProductId());
                inventoryLog.setChangeType(2); // 出库
                inventoryLog.setQuantityChange(-item.getQuantity());
                inventoryLog.setCurrentStock(productInfo.getStockQuantity());
                inventoryLog.setOperator("系统自动扣减");
                inventoryLog.setRemark("订单号：" + orderNo);
                int insertLogResult = inventoryLogMapper.insert(inventoryLog);
                if (insertLogResult <= 0) {
                    throw new BusinessException("999999", "系统异常");
                }
            }

            // 7. 清空购物车中已下单的商品
            QueryWrapper<ShoppingCartDO> cartQueryWrapper = new QueryWrapper<>();
            cartQueryWrapper.eq("user_id", createOrderDTO.getUserId());
            shoppingCartMapper.delete(cartQueryWrapper);

            return new RestResult<>("000000", "调用成功", true);
        } catch (BusinessException e) {
            log.error(e.getMessage(), e);
            return new RestResult<>(e.getCode(), e.getMsg()); // 修正此处调用
        } catch (Exception e) {
            log.error("创建订单发生未知错误", e);
            return new RestResult<>("999999", "系统异常");
        }
    }

    @Override
    public RestResult<OrderInfoDO> queryOrderDetail(QueryOrderDetailDTO queryOrderDetailDTO) {
        try {
            // 1. 根据订单ID查询订单基本信息
            QueryWrapper<OrderInfoDO> orderQueryWrapper = new QueryWrapper<>();
            orderQueryWrapper.eq("order_id", queryOrderDetailDTO.getOrderId());
            OrderInfoDO orderInfo = orderInfoMapper.selectOne(orderQueryWrapper);
            if (orderInfo == null) {
                return new RestResult<>("000001", "订单不存在");
            }

            // 2. 获取该订单下的所有商品项
            QueryWrapper<OrderItemDO> itemQueryWrapper = new QueryWrapper<>();
            itemQueryWrapper.eq("order_id", queryOrderDetailDTO.getOrderId());
            List<OrderItemDO> orderItems = orderItemMapper.selectList(itemQueryWrapper);

            // 构建返回数据（这里简化处理，实际项目可封装专门的数据传输对象）
            orderInfo.setItems(orderItems);

            return new RestResult<>("000000", "调用成功", orderInfo);
        } catch (Exception e) {
            log.error("查询订单详情发生错误", e);
            return new RestResult<>("999999", "系统异常");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResult<Boolean> updateOrderStatus(UpdateOrderStatusDTO updateOrderStatusDTO) {
        try {
            // 1. 检查订单是否存在
            QueryWrapper<OrderInfoDO> orderQueryWrapper = new QueryWrapper<>();
            orderQueryWrapper.eq("order_id", updateOrderStatusDTO.getOrderId());
            OrderInfoDO orderInfo = orderInfoMapper.selectOne(orderQueryWrapper);
            if (orderInfo == null) {
                return new RestResult<>("000001", "订单不存在");
            }

            // 2. 判断当前订单状态是否允许更改为目标状态
            Integer currentStatus = orderInfo.getOrderStatus();
            Integer targetStatus = updateOrderStatusDTO.getOrderStatus();
            if (!isValidStatusTransition(currentStatus, targetStatus)) {
                return new RestResult<>("000001", "不支持的状态变更操作");
            }

            // 3. 更新订单状态字段
            orderInfo.setOrderStatus(targetStatus);
            int updateResult = orderInfoMapper.updateById(orderInfo);
            if (updateResult <= 0) {
                throw new BusinessException("999999", "系统异常");
            }

            return new RestResult<>("000000", "调用成功", true);
        } catch (BusinessException e) {
            log.error(e.getMessage(), e);
            return new RestResult<>(e.getCode(), e.getMsg()); // 修正此处调用
        } catch (Exception e) {
            log.error("更新订单状态发生错误", e);
            return new RestResult<>("999999", "系统异常");
        }
    }

    /**
     * 验证订单状态转换是否合法
     */
    private boolean isValidStatusTransition(Integer currentStatus, Integer targetStatus) {
        // 实际业务逻辑需根据需求完善
        return true;
    }
}


    /**
     * 判断订单状态转换是否合法
     * @param from 当前状态
     * @param to 目标状态
     * @return 是否合法
     */
    private boolean isValidStatusTransition(Integer from, Integer to) {
        switch (from) {
            case 1: // 待付款 -> 已付款、已取消
                return to.equals(2) || to.equals(5);
            case 2: // 已付款 -> 已发货、已取消
                return to.equals(3) || to.equals(5);
            case 3: // 已发货 -> 已完成、已取消
                return to.equals(4) || to.equals(5);
            default:
                return false;
        }
    }
}